// 地图系统类
// 简单可复现的伪随机数发生器（mulberry32）
function createRNG(seed) {
    let t = (seed >>> 0) || 0;
    return function() {
        t += 0x6D2B79F5;
        let x = Math.imul(t ^ (t >>> 15), t | 1);
        x ^= x + Math.imul(x ^ (x >>> 7), x | 61);
        return ((x ^ (x >>> 14)) >>> 0) / 4294967296;
    };
}

class MapSystem {
    constructor(seed) {
        this.maxFloor = 15;
        this.currentFloor = 1;
        this.visitedNodes = new Set();
        this.availableNodes = new Set();
        this.seed = (typeof seed === 'number') ? (seed >>> 0) : (Date.now() >>> 0);
        this.rng = createRNG(this.seed);
        this.mapData = this.generateMapData(this.rng);
    }

    // 生成地图数据
    generateMapData(rng = Math.random) {
        const mapData = [];
        
        for (let floor = 1; floor <= this.maxFloor; floor++) {
            const floorData = {
                floor: floor,
                nodes: []
            };
            
            if (floor === 1) {
                // 第一层只有一个起始节点
                floorData.nodes.push({
                    id: `floor-${floor}-node-1`,
                    type: 'battle',
                    floor: floor,
                    available: true
                });
            } else if (this.isEliteFloor(floor)) {
                // 精英楼层：2个精英节点
                floorData.nodes.push({
                    id: `floor-${floor}-elite-1`,
                    type: 'elite',
                    floor: floor,
                    available: false
                });
                floorData.nodes.push({
                    id: `floor-${floor}-elite-2`,
                    type: 'elite',
                    floor: floor,
                    available: false
                });
            } else if (this.isBossFloor(floor)) {
                // Boss楼层：2个Boss节点
                floorData.nodes.push({
                    id: `floor-${floor}-boss-1`,
                    type: 'boss',
                    floor: floor,
                    available: false
                });
                floorData.nodes.push({
                    id: `floor-${floor}-boss-2`,
                    type: 'boss',
                    floor: floor,
                    available: false
                });
            } else {
                // 普通楼层：4个节点（战、汉、商、事），使用rng随机排列，保证每层恰有1个事件节点
                const nodeTypes = ['battle', 'hanfu', 'shop', 'event'];
                // 洗牌（Fisher-Yates）
                for (let i = nodeTypes.length - 1; i > 0; i--) {
                    const j = Math.floor(rng() * (i + 1));
                    const tmp = nodeTypes[i];
                    nodeTypes[i] = nodeTypes[j];
                    nodeTypes[j] = tmp;
                }
                nodeTypes.forEach((type, idx) => {
                    floorData.nodes.push({
                        id: `floor-${floor}-${type}-${idx + 1}`,
                        type: type,
                        floor: floor,
                        available: false
                    });
                });
            }
            
            mapData.push(floorData);
        }
        
        return mapData;
    }

    // 检查是否是精英楼层
    isEliteFloor(floor) {
        return floor === 4 || floor === 8 || floor === 12;
    }

    // 检查是否是Boss楼层
    isBossFloor(floor) {
        return floor === 15;
    }

    // 获取当前楼层的可用节点
    getCurrentFloorNodes() {
        if (this.currentFloor > this.maxFloor) return [];
        return this.mapData[this.currentFloor - 1].nodes;
    }

    // 获取下一楼层的可用节点
    getNextFloorNodes() {
        if (this.currentFloor >= this.maxFloor) return [];
        return this.mapData[this.currentFloor].nodes;
    }

    // 设置节点为可用
    setNodeAvailable(nodeId) {
        this.availableNodes.add(nodeId);
    }

    // 设置节点为已访问
    setNodeVisited(nodeId) {
        this.visitedNodes.add(nodeId);
        this.availableNodes.delete(nodeId);
    }

    // 检查节点是否可用
    isNodeAvailable(nodeId) {
        return this.availableNodes.has(nodeId);
    }

    // 检查节点是否已访问
    isNodeVisited(nodeId) {
        return this.visitedNodes.has(nodeId);
    }

    // 移动到下一层
    moveToNextFloor() {
        if (this.currentFloor < this.maxFloor) {
            this.currentFloor++;
            // 解锁下一层的所有节点
            this.getCurrentFloorNodes().forEach(node => {
                this.setNodeAvailable(node.id);
            });
        }
    }

    // 选择节点
    selectNode(nodeId) {
        if (!this.isNodeAvailable(nodeId)) return null;
        
        const node = this.findNodeById(nodeId);
        if (!node) return null;
        
        // 标记当前节点为已访问
        this.setNodeVisited(nodeId);
        
        // 将同层的其他节点标记为不可用
        const sameFloorNodes = this.getCurrentFloorNodes();
        sameFloorNodes.forEach(n => {
            if (n.id !== nodeId && !this.isNodeVisited(n.id)) {
                // 从可用节点中移除
                this.availableNodes.delete(n.id);
                console.log(`节点 ${n.id} 已被锁定（同层其他节点已选择）`);
            }
        });
        
        return node;
    }

    // 根据ID查找节点
    findNodeById(nodeId) {
        for (const floorData of this.mapData) {
            for (const node of floorData.nodes) {
                if (node.id === nodeId) {
                    return node;
                }
            }
        }
        return null;
    }

    // 获取节点类型
    getNodeType(nodeId) {
        const node = this.findNodeById(nodeId);
        return node ? node.type : null;
    }

    // 重置地图
    reset() {
        this.currentFloor = 1;
        this.visitedNodes.clear();
        this.availableNodes.clear();
        // 复用同一seed确保复现
        this.rng = createRNG(this.seed);
        this.mapData = this.generateMapData(this.rng);
        // 解锁第一层
        this.getCurrentFloorNodes().forEach(node => {
            this.setNodeAvailable(node.id);
        });
    }

    // 允许外部重设种子并重建地图
    setSeed(newSeed) {
        this.seed = (newSeed >>> 0);
        this.reset();
    }

    // 获取地图状态
    getMapState() {
        return {
            currentFloor: this.currentFloor,
            maxFloor: this.maxFloor,
            visitedNodes: Array.from(this.visitedNodes),
            availableNodes: Array.from(this.availableNodes),
            mapData: this.mapData
        };
    }
}

// 地图渲染器
class MapRenderer {
    constructor(mapSystem) {
        this.mapSystem = mapSystem;
        this.container = null;
    }

    // 渲染地图
    renderMap(containerId) {
        this.container = document.getElementById(containerId);
        if (!this.container) return;

        this.container.innerHTML = '';

        // 渲染每一层
        for (let floor = 1; floor <= this.mapSystem.maxFloor; floor++) {
            const floorElement = this.createFloorElement(floor);
            this.container.appendChild(floorElement);
        }
    }

    // 创建楼层元素
    createFloorElement(floor) {
        const floorDiv = document.createElement('div');
        floorDiv.className = 'map-floor';
        floorDiv.innerHTML = `<div class="floor-label">第 ${floor} 层</div>`;

        const nodesContainer = document.createElement('div');
        nodesContainer.className = 'floor-nodes';
        nodesContainer.style.display = 'flex';
        nodesContainer.style.gap = '20px';
        nodesContainer.style.justifyContent = 'center';
        nodesContainer.style.marginBottom = '20px';

        const floorData = this.mapSystem.mapData[floor - 1];
        floorData.nodes.forEach(node => {
            const nodeElement = this.createNodeElement(node);
            nodesContainer.appendChild(nodeElement);
        });

        floorDiv.appendChild(nodesContainer);
        return floorDiv;
    }

    // 创建节点元素
    createNodeElement(node) {
        const nodeDiv = document.createElement('div');
        nodeDiv.className = `map-node ${node.type}-node`;
        nodeDiv.id = node.id;
        nodeDiv.textContent = this.getNodeText(node);

        // 设置节点状态
        if (this.mapSystem.isNodeVisited(node.id)) {
            nodeDiv.classList.add('visited');
        } else if (this.mapSystem.isNodeAvailable(node.id)) {
            nodeDiv.classList.add('available');
        } else {
            nodeDiv.classList.add('unavailable');
        }

        // 检查是否是同层其他节点（已选择同层的某个节点后，其他节点变为不可用）
        if (!this.mapSystem.isNodeVisited(node.id) && !this.mapSystem.isNodeAvailable(node.id)) {
            // 检查是否在同层已有节点被访问
            const sameFloorNodes = this.mapSystem.getCurrentFloorNodes();
            const hasSameFloorVisited = sameFloorNodes.some(n => {
                return n.id !== node.id && this.mapSystem.isNodeVisited(n.id);
            });
            
            if (hasSameFloorVisited) {
                // 同层已有节点被访问，标记为已锁定
                nodeDiv.classList.add('locked');
            }
        }

        // 如果是当前楼层，添加当前标记
        if (node.floor === this.mapSystem.currentFloor) {
            nodeDiv.classList.add('current');
        }

        // 添加点击事件
        nodeDiv.addEventListener('click', () => {
            if (this.mapSystem.isNodeAvailable(node.id)) {
                this.onNodeClick(node);
            }
        });

        return nodeDiv;
    }

    // 获取节点文本
    getNodeText(node) {
        switch (node.type) {
            case 'battle':
                return '战';
            case 'elite':
                return '精';
            case 'boss':
                return 'B';
            case 'hanfu':
                return '汉';
            case 'shop':
                return '商';
            case 'event':
                return '事';
            default:
                return '?';
        }
    }

    // 节点点击事件
    onNodeClick(node) {
        // 这个函数会被游戏引擎重写
        console.log('Node clicked:', node);
    }

    // 更新地图显示
    updateMap() {
        if (this.container) {
            this.renderMap(this.container.id);
        }
    }

    // 设置节点点击回调
    setNodeClickCallback(callback) {
        this.onNodeClick = callback;
    }
}
